package midi;

import java.util.Vector;

import javax.sound.midi.MidiDevice;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiUnavailableException;

/**
 * Class: MidiHelpers.java
 * Description: Some utility function for finding
 * available MIDI devices.
 * Got this from here:
 * http://www.jsresources.org/examples/MidiInDump.html
 * @author Matthias Pfisterer and Florian Bomers
 */
public class MidiHelpers
{
	
	
	/**
	 * Returns a list of all the available MIDI input devices.
	 * @return Vector of MIDI input devices.
	 */
	public static Vector <String> getInputMidiDevices()
	{
		// Vector of device names to be returned
		Vector <String> deviceNames = new Vector <String>();
		
		// All the devices (input and output) available
		MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
		
		for (int i = 0; i < devices.length; i++)
		{
			try
			{
				MidiDevice device = MidiSystem.getMidiDevice(devices[i]);
				
				// Is this devices able to transmit a MIDI signal
				if(device.getMaxTransmitters() != 0)
				{
					deviceNames.addElement(devices[i].getName());
				}
			}
			catch(MidiUnavailableException mue)
			{
				System.out.println("Midi Device Unavailable.");
				System.err.println(mue);
			}
		}
		
		// No MIDI input devices found. =(
		if (deviceNames.size() == 0)
		{
			deviceNames.addElement("No MIDI input devices available.");
		}

		return deviceNames;
	}
	
	



	/** Retrieve a MidiDevice.Info for a given name.

	This method tries to return a MidiDevice.Info whose name
	matches the passed name. If no matching MidiDevice.Info is
	found, null is returned.  If bForOutput is true, then only
	output devices are searched, otherwise only input devices.

	@param strDeviceName the name of the device for which an info
	object should be retrieved.

	@param bForOutput If true, only output devices are
	considered. If false, only input devices are considered.

	@return A MidiDevice.Info object matching the passed device
	name or null if none could be found.

	*/
	public static MidiDevice.Info getMidiDeviceInfo(String strDeviceName, boolean bForOutput)
	{
		MidiDevice.Info[]	aInfos = MidiSystem.getMidiDeviceInfo();
		for (int i = 0; i < aInfos.length; i++)
		{
			if (aInfos[i].getName().equals(strDeviceName))
			{
				try
				{
					MidiDevice device = MidiSystem.getMidiDevice(aInfos[i]);
					boolean	bAllowsInput = (device.getMaxTransmitters() != 0);
					boolean	bAllowsOutput = (device.getMaxReceivers() != 0);
					if ((bAllowsOutput && bForOutput) || (bAllowsInput && !bForOutput))
					{
						return aInfos[i];
					}
				}
				catch (MidiUnavailableException e)
				{
					// TODO:
				}
			}
		}
		return null;
	}
}